/****************************************************************************
**
** This file is part of the Qt Extended Opensource Package.
**
** Copyright (C) 2008 Trolltech ASA.
**
** Contact: Qt Extended Information (info@qtextended.org)
**
** This file may be used under the terms of the GNU General Public License
** version 2.0 as published by the Free Software Foundation and appearing
** in the file LICENSE.GPL included in the packaging of this file.
**
** Please review the following information to ensure GNU General Public
** Licensing requirements will be met:
**     http://www.fsf.org/licensing/licenses/info/GPLv2.html.
**
****************************************************************************/

#include "phonebookdialog.h"
#include <QDebug>

PhoneBookDialog::PhoneBookDialog(QWidget *parent, Qt::WFlags f)
    : QWidget(parent, f)
{
    setupUi(this);

    myPhoneBook = new NeoPhoneBook();
    myPhoneBook->loadPhoneBook();

    selection = 0; // can only be 0 ~ 4
	int index = -1;
	for (int i=0; i<5; i++) {
		if (index <= myPhoneBook->getNumEntries()-1) {
			slotIndex << index++;
		} else {
			slotIndex << -2;
		}
	}

	// set layout
	firstContact->setAlignment(Qt::AlignCenter);
	//firstContact->setAutoFillBackground(false);
	secondContact->setAlignment(Qt::AlignCenter);
	//secondContact->setAutoFillBackground(false);
	thirdContact->setAlignment(Qt::AlignCenter);
	//thirdContact->setAutoFillBackground(false);
	forthContact->setAlignment(Qt::AlignCenter);
	//forthContact->setAutoFillBackground(false);
	fifthContact->setAlignment(Qt::AlignCenter);
	//fifthContact->setAutoFillBackground(false);

	// connection

    updateScreen(REFRESH);
}

PhoneBookDialog::~PhoneBookDialog()
{
    // Do nothing for now
}

/**
 * Update the contact slot at 'index' with the text 'name'.
 * @param index the index of contact slot from 0 to 4.
 * @param name the contact name to show.
 */
void PhoneBookDialog::updateContactSlot(int index, QString name)
{    
	switch (index) {
	case 0:
		firstContact->setText(name);
		if (selection == index) {
			firstContact->setPalette(QPalette(Qt::blue));
		} else {
			firstContact->setPalette(QPalette(Qt::black));
		}
		return;
	case 1:
		secondContact->setText(name);
		if (selection == index) {
			secondContact->setPalette(QPalette(Qt::blue));
		} else {
			secondContact->setPalette(QPalette(Qt::black));
		}
		return;
	case 2:
		thirdContact->setText(name);
		if (selection == index) {
			thirdContact->setPalette(QPalette(Qt::blue));
		} else {
			thirdContact->setPalette(QPalette(Qt::black));
		}
		return;
	case 3:
		forthContact->setText(name);
		if (selection == index) {
			forthContact->setPalette(QPalette(Qt::blue));
		} else {
			forthContact->setPalette(QPalette(Qt::black));
		}
		return;
	case 4:
		fifthContact->setText(name);
		if (selection == index) {
			fifthContact->setPalette(QPalette(Qt::blue));
		} else {
			fifthContact->setPalette(QPalette(Qt::black));
		}
		return;
	default:
		qDebug() << "updateContactSlot: Invalid index";
		return;
	}
}

void PhoneBookDialog::updateScreen(Update_Types type)
{
    // updates the 5 contact slots for scrolling or refreshing
	switch (type) {
	case UP:
		if (selection == 0) return;
		if (selection > 1) {
			selection--;
		} else {
			if (slotIndex.at(0) == -1) {
				selection--;
			} else {
					int top = slotIndex.at(4);
				for (int i=4; i>-1; i--) {
					slotIndex.replace(i, --top);
				}
			}
		}
		updateScreen(REFRESH);
		return;

	case DOWN:
		if (selection == 4) return;
		if (selection < 3 && slotIndex.at(selection + 1) != -2) {
			selection++;
		} else { // selection == 3
			if (slotIndex.at(selection + 1) == -2) return;
			if (slotIndex.at(4) == myPhoneBook->getNumEntries() - 1) {
				selection++;				
			} else {
				int bottom = slotIndex.at(0);
				for (int i=0; i<5; i++) {				
					slotIndex.replace(i, ++bottom);
				}
			}			
		}		
		updateScreen(REFRESH);
		return;

	case REFRESH:
		for (int i=0; i<5; i++) {
			int index = slotIndex.at(i);
			if (index == -1) {
				updateContactSlot(i, "New Contact");
			} else {				
				if (index == -2) {
					updateContactSlot(i, "");
				} else {
					NeoPhoneBookEntry *entry = myPhoneBook->getElementAt(index);
					updateContactSlot(i, entry->getContactName());
				}				
			}
		}		
		return;

	case DELETE_LAST:
		return;

	default:
		return;
	}
}

void PhoneBookDialog::addContact(NeoPhoneBookEntry *newEntry)
{
    // add contact to the phonebook and refresh screen
	qDebug() << "add" <<newEntry->getContactName();
	int index = myPhoneBook->addEntry(newEntry);
	updateScreen(REFRESH);
	jumpTo(index);
}

void PhoneBookDialog::replaceContact(NeoPhoneBookEntry *newEntry)
{
    // replace contact in the phonebook and refresh screen
	qDebug() << "replace" << newEntry->getContactName();
	int index = myPhoneBook->replaceEntry(slotIndex.at(selection), newEntry);
	updateScreen(REFRESH);
	jumpTo(index);
}

void PhoneBookDialog::deleteContact(int index)
{
    // delete contact in the phonebook
	int maxIndex;
	myPhoneBook->deleteEntry(index);

	if (selection == 4) { // at the end
		if (slotIndex.at(0) == -1) {
			selection--;
			slotIndex.replace(4, -2);	
		} else {
			for (int i=0; i<5; i++) {
				slotIndex.replace(i, slotIndex.at(i)-1);
			}
		}			
	} else { 
		maxIndex = myPhoneBook->getNumEntries() - 1;
		// back not ok
		if ((slotIndex.at(selection)+(4-selection)) > maxIndex) {
			if (slotIndex.at(0) == -1) { // front not ok
				for (int i=1; i<=(maxIndex+1); i++) {
					slotIndex.replace(i, i-1);
				}
				for (int i=(maxIndex+2); i<5; i++) {
					slotIndex.replace(i, -2);
				}
				if (slotIndex.at(selection)==-2) selection--;
			} else { // front ok
				for (int i=0; i<5; i++) {
					slotIndex.replace(i, slotIndex.at(i)-1);
				}
			}	
		}
	}
	qDebug()<<slotIndex.at(0)<<slotIndex.at(1)
			<<slotIndex.at(2)<<slotIndex.at(3)<<slotIndex.at(4);
	updateScreen(REFRESH);
}

void PhoneBookDialog::on_searchLineEdit_textChanged(const QString &text)
{
	if (text.isEmpty()) return;
	int index = myPhoneBook->searchContact(text);
	jumpTo(index);
	qDebug()<<"search for"<<text;
}

void PhoneBookDialog::on_upButton_clicked()
{
	searchLineEdit->setText("");
    updateScreen(UP);
}

void PhoneBookDialog::on_downButton_clicked()
{
	searchLineEdit->setText("");
    updateScreen(DOWN);
}

void PhoneBookDialog::on_selectButton_clicked()
{		
	int index = slotIndex.at(selection);
	if (index == -1) { 
		openAddContactDialogForAdd();
	} else { 
		//openAddContactDialogForEdit(index);
		ViewContactDialog *myViewContactDialog = new ViewContactDialog();
		myViewContactDialog->setAttribute(Qt::WA_DeleteOnClose);
		myViewContactDialog->setupView(index, myPhoneBook->getElementAt(index));
		QObject::connect(myViewContactDialog, 
				SIGNAL(editContactSignal(int)), 
				this, SLOT(openAddContactDialogForEdit(int)));
		QObject::connect(myViewContactDialog, 
				SIGNAL(deleteContactSignal(int)), 
				this, SLOT(deleteContact(int)));
		myViewContactDialog->showMaximized();
	}
}

/**
 * Prompt user to be able to delete the selected contact
 */
void PhoneBookDialog::on_deleteButton_clicked()
{	
	if (slotIndex.at(selection) == -1) return;

	QMessageBox msgBox;
    msgBox.setWindowTitle("Delete Contact");
    msgBox.setIcon(QMessageBox::Information);
    msgBox.setText("Do you really want to do that?");
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);	
	
    switch (msgBox.exec()) {	
    case QMessageBox::Yes:
		deleteContact(slotIndex.at(selection));
		break;
    case QMessageBox::No:
        break;
    default:
        break;
    }
}

void PhoneBookDialog::openAddContactDialogForAdd()
{
	AddContactDialog *myAddContactDialog = new AddContactDialog();
	myAddContactDialog->setAttribute(Qt::WA_DeleteOnClose);
	QObject::connect(myAddContactDialog, 
			SIGNAL(updateContactSignal(NeoPhoneBookEntry*)), 
			this, SLOT(addContact(NeoPhoneBookEntry*)));
	myAddContactDialog->showMaximized();
}
void PhoneBookDialog::openAddContactDialogForEdit(int index)
{	
	AddContactDialog *myAddContactDialog = new AddContactDialog();
	myAddContactDialog->setAttribute(Qt::WA_DeleteOnClose);
	myAddContactDialog->setupEdit(myPhoneBook->getElementAt(index));
	QObject::connect(myAddContactDialog, 
			SIGNAL(updateContactSignal(NeoPhoneBookEntry*)), 
			this, SLOT(replaceContact(NeoPhoneBookEntry*)));
	myAddContactDialog->showMaximized();
}

void PhoneBookDialog::jumpTo(int jumpToIndex)
{	
	int currentIndex = slotIndex.at(selection);
	while (currentIndex != jumpToIndex) {	
		
		if (currentIndex > jumpToIndex) {
			updateScreen(UP);
		} else { // currentIndex < jumpToIndex
			updateScreen(DOWN);
		}
	  	currentIndex = slotIndex.at(selection);
	} 
}
